package edu.ccut.saturn.studio.core.util.eclipse;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.eclipse.core.resources.IProject;

/**
 * @author 郭英杰
 * @version 1.0 2008.9.4
 */
public final class SaturnBundleUtil {

	public static final String BUNDLE_SEPARATOR = ":";

	private static final String META_NAME = "META-INF";
	private static final String META_NAME_FILE = "MANIFEST.MF";
	private static final String BUNDLE_NAME = "Bundle-SymbolicName";

	private SaturnBundleUtil() {

	}

	public static File getProjectBundleFile(IProject project) {
		StringBuffer bundleFilePath = new StringBuffer(project.getLocation()
				.toOSString());

		bundleFilePath.append(File.separator).append(META_NAME).append(
				File.separator).append(META_NAME_FILE);

		return new File(bundleFilePath.toString());
	}

	public static String getBundleSymbolicName(IProject project)
			throws Exception {

		String path = getProjectBundleFile(project).getPath();

		return getSimpleSybolicName(getBundleAttribute(path, BUNDLE_NAME));
	}

	public static String getBundleSymbolicName(JarFile jarFile)
			throws Exception {

		return getSimpleSybolicName(getBundleAttribute(jarFile, BUNDLE_NAME));
	}

	public static String getBundleSymbolicName(InputStream input)
			throws Exception {

		return getSimpleSybolicName(getBundleAttribute(input, BUNDLE_NAME));
	}

	public static String getBundleSymbolicName(String path) throws Exception {

		return getSimpleSybolicName(getBundleAttribute(path, BUNDLE_NAME));
	}

	private static String getSimpleSybolicName(String value) {
		if (value != null && value.contains(";")) {
			int index = value.indexOf(";");
			return value.substring(0, index).trim();
		}

		return value;
	}

	public static String getBundleAttribute(JarFile jarFile, String keywords)
			throws Exception {

		Enumeration<JarEntry> jarEntries = jarFile.entries();

		while (jarEntries.hasMoreElements()) {
			JarEntry jarEntry = jarEntries.nextElement();

			if (jarEntry.getName().endsWith(META_NAME_FILE)) {
				InputStream in = null;

				try {
					in = jarFile.getInputStream(jarEntry);
					return getBundleAttribute(in, keywords);
				} finally {
					if (in != null) {
						try {
							in.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}

		return null;
	}

	public final static String getBundleAttribute(IProject project, String key)
			throws Exception {
		String path = getProjectBundleFile(project).getPath();

		return getBundleAttribute(path, key);
	}

	public final static String getBundleAttribute(InputStream input, String key)
			throws Exception {

		BufferedReader bufferedReader = null;
		String line = null;
		String value = null;

		InputStreamReader isr = new InputStreamReader(input);
		bufferedReader = new BufferedReader(isr);

		while ((line = bufferedReader.readLine()) != null) {
			value = getSimpleLineKeyValue(line, key);

			if (value != null) {
				if (value.endsWith(",")) {
					while ((line = bufferedReader.readLine()) != null) {
						String subValue = line.trim();

						value += subValue;

						if (!subValue.endsWith(",")) {
							break;
						}
					}
				}

				break;
			}
		}

		return value;
	}

	/**
	 * 解析Bundle-INF文件，根据key解析文件 (requier-bundle)
	 * 
	 * @param path
	 * @param key
	 * @return
	 */
	public static String getBundleAttribute(String path, String key)
			throws Exception {

		InputStream in = null;

		try {
			in = new FileInputStream(new File(path));

			return getBundleAttribute(in, key);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 根据KEY 值 解析文件
	 * 
	 * @param line
	 * @param key
	 * @return
	 */
	private static String getSimpleLineKeyValue(String line, String key) {
		int index = line.indexOf(BUNDLE_SEPARATOR);

		String lineKey = null;
		if (index != -1) {
			lineKey = line.substring(0, index).trim();
			if (lineKey != null && lineKey.equalsIgnoreCase(key)) {
				return line.substring(index + 1).trim();
			}
		}

		return null;
	}
}
